#pragma once
#include <iostream>
#include <vector>
#include <sstream>
#include <fstream>
#include <unordered_map>
#include"Log.hpp"

static const std::string file404 = "Wroot/404.html";
static const std::string homepage = "index.html";
static const std::string httpversion = "HTTP/1.0";
static const std::string Wroot = "Wroot";
static const std::string redir = "/redir";
static const std::string sep = "\r\n";
static const std::string header_sep = ": ";
static const std::string suffix_sep = ".";
static const std::string space = " ";
static const std::string args_sep = "?";

class HttpRequest
{
private:
    // 获取每一行
    std::string GetOneLine(std::string &req)
    {
        if (req.empty())
            return req;

        std::string line;
        auto pos = req.find(sep);
        if (pos == std::string::npos)
        {
            return std::string();
        }
        line = req.substr(0, pos);
        req.erase(0, pos + sep.size());
        return line.empty() ? sep : line;
    }
    bool ParseHeaderHelper(std::string &line, std::string *k, std::string *v)
    {
        auto pos = line.find(header_sep);
        if (pos == std::string::npos)
            return false;
        *k = line.substr(0, pos);
        *v = line.substr(pos + header_sep.size());
        return true;
    }
    void ParseReqHeader()
    {
        for (auto str : _req_header)
        {
            std::string k;
            std::string v;
            if (ParseHeaderHelper(str, &k, &v))
            {
                _header_map.insert(std::make_pair(k, v));
            }
        }
    }
    void ParseReqLine()
    {
        if (_req_line.empty())
            return;
        std::stringstream ss(_req_line);
        ss >> _method >> _url >> _version;
        if(_method=="GET")
        {
            auto pos=_url.find(args_sep);
            if(pos!=std::string::npos)
            {
                _args=_url.substr(pos+args_sep.size());
                _url.resize(pos);
            }
        }

        _path += _url;
        //Log(DEBUG,"url:%s",_url.c_str());
        if(_path[_path.size()-1]=='/')
        {
            _path+=homepage;
        }
        auto pos = _url.rfind(suffix_sep);
        if (pos != std::string::npos)
            _suffix = _url.substr(pos);
        else
        {
            _suffix= ".unknown";
        }
        //Log(DEBUG,"path:%s, suffix: %s",_path.c_str(),_suffix.c_str());
    }

public:
    HttpRequest()
        : _blank_line(sep), _path(Wroot)
    {
    }
    // 序列化
    void resialize()
    {
    }
    // 反序列化
    void Dresialize(std::string &reqstr)
    {
        // 获取请求行
        _req_line = GetOneLine(reqstr);
        while (true)
        {
            std::string line = GetOneLine(reqstr);

            if (line.empty())
            {
                // 获取到的字符串为空
                break;
            }
            else if (line == sep)
            {
                // 返回的是空行，reqstr中剩余的就是正文
                _req_body = reqstr;
                break;
            }
            else
            {
                // 请求头部
                _req_header.emplace_back(line);
            }
        }
        ParseReqLine();
        ParseReqHeader();
    }
    void Print()
    {
        std::cout << "####" << _req_line << std::endl;
        for (auto e : _header_map)
        {
            std::cout << e.first << ": " << e.second << std::endl;
        }
        std::cout << "####" << _req_body << std::endl;

        std::cout << _method << " " << _url << " " << _path << " " << _version << " " << _suffix << std::endl;
    }
    std::string methond()
    {
        return _method;
    }
    std::string url()
    {
        return _url;
    }
    std::string suffix()
    {
        return _suffix;
    }
    std::string version()
    {
        return _version;
    }
    std::string args()
    {
        return _args;
    }
     std::string path()
    {
        return _path;
    }
    ~HttpRequest() {}

private:
    // 原始的
    std::string _req_line;                // 请求行
    std::vector<std::string> _req_header; // 请求头部
    std::string _blank_line;              // 空行
    std::string _req_body;                // 请求正文
    // 想要解析得到的
    std::string _method;  // 请求方法
    std::string _url;     // 域名
    std::string _path;    // 要访问的资源路径
    std::string _suffix;  // 后缀
    std::string _version; // http版本
    std::string _args;    // 如果以get方法提交表单，获取其参数
    std::unordered_map<std::string, std::string> _header_map;
};

// 应答报文协议
class HttpResponse
{
public:
    HttpResponse()
        : _version(httpversion), _blank_line(sep)
    {
    }

    std::string Resialize()
    {
        std::string respstr;
        _status_line = _version + space + std::to_string(_code) + space + _desc + sep;
        respstr += _status_line;
        for (auto header : _headers_map)
        {
            _headers.emplace_back(header.first + header_sep + header.second + sep);
        }
        for (auto header : _headers)
        {
            respstr += header;
        }
        respstr += _blank_line;
        respstr += _resp_body;
        return respstr;
    }
    void Dresialize()
    {
    }
    void AddStatusLine(int code, const std::string &desc)
    {
        _code = code;
        _desc = desc;
    }
    void AddHeader(const std::string &k, const std::string &v)
    {
        //Log(DEBUG, "addheader k:%s,v:%s", k.c_str(), v.c_str());
        _headers_map[k] = v;
    }
    void AddRespBody(const std::string &text)
    {
        _resp_body = text;
    }
    ~HttpResponse() {}

private:
    // 构建应答的必要字段
    std::string _version;
    int _code;
    std::string _desc;
    std::unordered_map<std::string, std::string> _headers_map;
    // 应答结构化字段
    std::string _status_line;
    std::vector<std::string> _headers;
    std::string _blank_line;
    std::string _resp_body;
};

class Factory
{
public:
    std::shared_ptr<HttpRequest> BuildHttpRequest()
    {
        return std::make_shared<HttpRequest>();
    }
    std::shared_ptr<HttpResponse> BuildHttpResponse()
    {
        return std::make_shared<HttpResponse>();
    }
};